package com.cloud.common.domain.template;

import com.cloud.common.domain.DefaultResult;
import com.cloud.common.domain.template.callback.DefaultCallback;
import com.cloud.common.exception.CloudException;
import com.cloud.common.exception.enums.ErrorEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionOperations;

import javax.annotation.Resource;

/**
 * 服务端默认模板模式
 *
 * @author wangjian
 * @version 1.0.0
 * @create 2020年10月26日 14:24
 * @since JDK 1.8
 * Life is so short,do something to make yourself happy,such as coding
 */
@Slf4j
@Component
public class DefaultServiceTemplate {

    /**
     * 事务模板
     */
    @Resource
    private TransactionOperations transactionTemplate;

    /**
     * 不带事务的模板实现
     *
     * @param defaultCallback
     * @return
     */
    public <T> DefaultResult<T> operate(final DefaultCallback<T> defaultCallback) {
        return execute(defaultCallback, false);
    }

    /**
     * 带事务的模板实现
     *
     * @param defaultCallback
     * @return
     */
    public <T> DefaultResult<T> operateWithTransaction(final DefaultCallback<T> defaultCallback) {
        return execute(defaultCallback, true);
    }

    /**
     * 执行服务端处理逻辑
     *
     * @return
     */
    private <T> DefaultResult<T> execute(final DefaultCallback<T> defaultCallback, final boolean withTransaction) {
        DefaultResult<T> result;
        try {
            //前置参数校验
            defaultCallback.checkParam();
            if (withTransaction) {

                transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                    @Override
                    protected void doInTransactionWithoutResult(TransactionStatus status) {
                        //服务端真实处理逻辑
                        defaultCallback.realExecute();
                    }
                });
            } else {
                //服务端真实处理逻辑
                defaultCallback.realExecute();
            }
            result = new DefaultResult<T>();
            result.setSuccess(true);
            result.setResultObj(defaultCallback.getReturnValue());
        } catch (CloudException e) {
            result = new DefaultResult<T>();
            result.setSuccess(false);
            result.setCode(e.getCode());
            result.setMsg(e.getMsg());
            result.setResultObj(null);
            log.warn("baseService cloud Exception，msg：{}", e.getMsg(), e);
        } catch (Exception e) {
            log.warn("baseService unknown Exception，msg：{}", e.getMessage(), e);
            result = new DefaultResult<T>();
            result.setSuccess(false);
            result.setCode(ErrorEnum.UNKNOWN.getCode());
            result.setMsg(e.getMessage());
            result.setResultObj(null);
            log.warn("baseService unknown Exception，msg：{}", e.getMessage(), e);
        }
        return result;
    }

}
